<!--
 * @Author: anxia.ack anchenkai@come-future.com
 * @Date: 2025-03-09 16:28:36
 * @LastEditors: anxia.ack anchenkai@come-future.com
 * @LastEditTime: 2025-04-05 11:53:46
 * @FilePath: /free-learning/src/views/system/school/index.vue
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
-->
<template>
  <el-card>
    <div class="search-bar">
      <el-form ref="searchFormRef" :inline="true" label-width="80px">
        <el-form-item label="学校名称">
          <el-input v-model="searchform.name" placeholder="请输入学校名称" clearable />
        </el-form-item>
        <el-form-item label="学校级别">
          <Dict
            v-model="searchform.level"
            code="school_level"
            type="select"
            placeholder="请选择学校级别"
            clearable
          />
        </el-form-item>
        <el-form-item label="所在地区">
          <RegionSelect
            v-model="regionArray"
            clearable
            :checkStrictly="true"
            @change="addressHandlerChange"
          />
        </el-form-item>
        <el-form-item>
          <el-button type="primary" :loading="loading" @click="handleSearch">
            <el-icon><Search /></el-icon>
            搜索
          </el-button>
          <el-button :disabled="loading" @click="handleReset">
            <el-icon><Refresh /></el-icon>
            重置
          </el-button>
        </el-form-item>
      </el-form>
    </div>

    <div class="operation-bar">
      <el-button type="primary" @click="handleAdd">新增学校</el-button>
    </div>

    <el-table
      v-loading="loading"
      element-loading-text="加载中..."
      element-loading-spinner="el-icon-loading"
      element-loading-background="rgba(0, 0, 0, 0.1)"
      :data="tableData"
      border
      style="width: 100%"
    >
      <el-table-column prop="name" width="150" label="学校名称" show-overflow-tooltip>
        <template #default="{ row }">
          <el-link
            v-if="row.website"
            type="primary"
            :href="row.website"
            target="_blank"
            :underline="false"
          >
            {{ row.name }}
          </el-link>
          <span v-else>{{ row.name }}</span>
        </template>
      </el-table-column>
      <el-table-column prop="logo" label="学校Logo" width="100">
        <template #default="{ row }">
          <el-image
            v-if="row.logo"
            :src="row.logo"
            style="width: 60px; height: 60px; object-fit: contain; border-radius: 4px"
            fit="cover"
          />
        </template>
      </el-table-column>
      <el-table-column prop="levelStr" width="120" label="学校级别" show-overflow-tooltip />
      <el-table-column label="地址" show-overflow-tooltip>
        <template #default="{ row }">
          {{
            [row.countryStr, row.provinceStr, row.cityStr, row.districtStr, row.address]
              .filter(Boolean)
              .join(" ")
          }}
        </template>
      </el-table-column>
      <el-table-column prop="phone" width="150" label="联系电话" show-overflow-tooltip />
      <el-table-column prop="email" width="200" label="邮箱" show-overflow-tooltip />
      <el-table-column label="操作" width="200" fixed="right">
        <template #default="{ row }">
          <el-button type="primary" link @click="handleEdit(row)">编辑</el-button>
          <el-button type="danger" link @click="handleDelete(row)">删除</el-button>
        </template>
      </el-table-column>
    </el-table>

    <div class="pagination">
      <el-pagination
        v-model:current-page="searchform.pageNum"
        v-model:page-size="searchform.pageSize"
        :total="total"
        :page-sizes="[10, 20, 50, 100]"
        layout="total, sizes, prev, pager, next"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
      />
    </div>

    <!-- 新增/编辑对话框 -->
    <el-dialog
      v-model="dialogVisible"
      :title="dialogType === 'add' ? '新增学校' : '编辑学校'"
      width="600px"
      @closed="handleDialogClosed"
    >
      <el-form ref="formRef" :model="form" :rules="rules" label-width="100px">
        <el-form-item label="学校名称" prop="name">
          <el-input v-model="form.name" placeholder="请输入学校名称" />
        </el-form-item>
        <el-form-item label="学校Logo" prop="logo">
          <ImageUpload v-model="form.logo" :limit="1" :maxSize="2" />
        </el-form-item>
        <el-form-item label="学校级别" prop="level">
          <Dict
            v-model="form.level"
            code="school_level"
            type="select"
            placeholder="请选择学校级别"
          />
        </el-form-item>
        <el-form-item label="地址" prop="address">
          <RegionSelect :key="dialogKey" v-model="addressArray" @change="handleAddressChange" />
        </el-form-item>
        <el-form-item label="详细地址" prop="address">
          <el-input v-model="form.address" placeholder="请输入详细地址" />
        </el-form-item>
        <el-form-item label="联系电话" prop="phone">
          <el-input v-model="form.phone" placeholder="请输入联系电话" />
        </el-form-item>
        <el-form-item label="邮箱" prop="email">
          <el-input v-model="form.email" placeholder="请输入邮箱" />
        </el-form-item>
        <el-form-item label="官网" prop="website">
          <el-input v-model="form.website" placeholder="请输入学校官网" />
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="dialogVisible = false">取消</el-button>
          <el-button type="primary" @click="handleSubmit">确定</el-button>
        </span>
      </template>
    </el-dialog>
  </el-card>
</template>

<script setup lang="ts">
import { RegionType } from "@/api/region/type";
import { SchoolPageQueryParams, SchoolType } from "@/api/school/type";
import { RegionLevelEnum } from "@/enums/RegionEnum";
import { pageQuery, saveAndUpdateSchool, deleteSchoolById } from "@/api/school";
import { ElMessage, ElMessageBox } from "element-plus";
import type { FormInstance, FormRules } from "element-plus";
import ImageUpload from "@/components/Upload/ImageUpload.vue";
import Dict from "@/components/Dict/index.vue";
import RegionSelect from "@/components/RegionSelect/index.vue";
import { useDictStore } from "@/store/modules/dict";
import { Search, Refresh } from "@element-plus/icons-vue";
import { ref, reactive, onMounted, watch, nextTick } from "vue";

defineOptions({
  name: "School",
});

const loading = ref(false);
const total = ref(0);
const tableData = ref<SchoolType[]>([]);
const dialogVisible = ref(false);
const dialogType = ref<"add" | "edit">("add");
const dialogKey = ref(0);
const formRef = ref<FormInstance>();
const dictStore = useDictStore();

const searchform = reactive<SchoolPageQueryParams>({
  pageNum: 1,
  pageSize: 10,
  name: "",
  level: 0,
  country: 0,
  province: 0,
  city: 0,
  district: 0,
});

const form = reactive<Partial<SchoolType>>({
  name: "",
  logo: "",
  level: 1,
  levelStr: "",
  address: "",
  phone: "",
  email: "",
  website: "",
  addressIds: [] as string[],
  country: 0,
  countryStr: "",
  province: 0,
  provinceStr: "",
  city: 0,
  cityStr: "",
  district: 0,
  districtStr: "",
});

const addressArray = ref<string[]>([]);

const rules = reactive<FormRules>({
  name: [
    { required: true, message: "请输入学校名称", trigger: "blur" },
    { min: 2, max: 50, message: "长度在 2 到 50 个字符", trigger: "blur" },
  ],
  level: [{ required: true, message: "请选择学校级别", trigger: "change" }],
  address: [
    { required: true, message: "请输入详细地址", trigger: "blur" },
    { min: 5, max: 200, message: "长度在 5 到 200 个字符", trigger: "blur" },
  ],
  phone: [
    { required: true, message: "请输入联系电话", trigger: "blur" },
    {
      pattern: /^((0\d{2,3}-?)?[1-9]\d{6,7}|1[3-9]\d{9})$/,
      message: "请输入正确的电话号码（支持手机号或座机号）",
      trigger: "blur",
    },
  ],
  email: [
    { required: true, message: "请输入邮箱", trigger: "blur" },
    {
      pattern: /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/,
      message: "请输入正确的邮箱地址",
      trigger: "blur",
    },
  ],
  website: [
    {
      pattern: /^(https?:\/\/)?([\da-z.-]+)\.([a-z.]{2,6})([/\w .-]*)*\/?$/,
      message: "请输入正确的网址",
      trigger: "blur",
    },
  ],
});

// 表单引用
const searchFormRef = ref();
// 地区选择存储区域数组，用于显示和重置
const regionArray = ref([]);

// 获取区域ID
const getRegionId = (regions: RegionType[], level: number) => {
  const countryRegion = regions?.find((item) => item?.level === level);
  return countryRegion ? +countryRegion.id : 0;
};

// 处理地址变化
const addressHandlerChange = (regions: RegionType[]) => {
  // 重置所有地区ID
  searchform.country = 0;
  searchform.province = 0;
  searchform.city = 0;
  searchform.district = 0;

  // 根据用户选择的地区级别设置相应的ID
  if (regions && regions.length > 0) {
    regions.forEach((region) => {
      switch (region.level) {
        case RegionLevelEnum.COUNTRY:
          searchform.country = +region.id;
          break;
        case RegionLevelEnum.PROVINCE:
          searchform.province = +region.id;
          break;
        case RegionLevelEnum.CITY:
          searchform.city = +region.id;
          break;
        case RegionLevelEnum.DISTRICT:
          searchform.district = +region.id;
          break;
      }
    });
  }
};

// 获取表格数据
const getTableData = async () => {
  loading.value = true;
  try {
    // 创建一个只包含分页信息的基础查询对象
    const params: any = {
      pageNum: searchform.pageNum,
      pageSize: searchform.pageSize,
    };

    // 只添加有值的查询参数
    if (searchform.name) {
      params.name = searchform.name;
    }
    if (searchform.level > 0) {
      params.level = searchform.level;
    }
    if (searchform.country) {
      params.country = searchform.country;
    }
    if (searchform.province) {
      params.province = searchform.province;
    }
    if (searchform.city) {
      params.city = searchform.city;
    }
    if (searchform.district) {
      params.district = searchform.district;
    }

    const res = await pageQuery(params);
    if (res) {
      // 使用 as any 断言避免类型错误
      tableData.value = (res as any).records || res.list || [];
      total.value = res.total || 0;
    }
  } catch (error) {
    console.error("获取学校列表失败:", error);
    ElMessage.error("获取学校列表失败");
  } finally {
    loading.value = false;
  }
};

// 搜索
const handleSearch = async () => {
  searchform.pageNum = 1;
  await getTableData();
};

// 重置
const handleReset = async () => {
  // 重置表单数据
  searchform.name = "";
  searchform.level = 0; // 使用 0 而不是 null
  searchform.country = 0;
  searchform.province = 0;
  searchform.city = 0;
  searchform.district = 0;
  searchform.pageNum = 1;

  // 重置地区选择数组
  regionArray.value = [];

  // 重新加载数据
  await getTableData();
};

// 新增
const handleAdd = () => {
  dialogType.value = "add";

  // 重置表单数据
  Object.assign(form, {
    name: "",
    logo: "",
    level: 1,
    levelStr: "",
    address: "",
    phone: "",
    email: "",
    website: "",
    addressIds: [] as string[],
    country: 0,
    countryStr: "",
    province: 0,
    provinceStr: "",
    city: 0,
    cityStr: "",
    district: 0,
    districtStr: "",
  });

  // 设置初始的 levelStr
  updateLevelStr(1);

  // 清空地区数组
  addressArray.value = [];

  // 增加 dialogKey，强制组件重新渲染
  dialogKey.value++;

  // 打开对话框
  dialogVisible.value = true;
};

// 编辑
const handleEdit = (row: SchoolType) => {
  dialogType.value = "edit";
  console.log(row, "row");
  addressArray.value = row.addressIds;
  // 复制数据到表单
  Object.assign(form, row);

  // 确保 levelStr 正确设置
  if (row.level && !row.levelStr) {
    updateLevelStr(row.level);
  }

  // 增加 dialogKey，强制组件重新渲染
  dialogKey.value++;

  // 打开对话框
  dialogVisible.value = true;

  // 对话框打开后，设置地区选择器的值
  // 使用 nextTick 确保组件已挂载
  nextTick(() => {
    initAddressArray(row);
  });
};

// 初始化地区数组
const initAddressArray = (row: SchoolType) => {
  console.log("初始化地区数组，当前数据:", row);

  // 清空地区数组
  addressArray.value = [];

  // 尝试设置地区数组
  if (row.addressIds && Array.isArray(row.addressIds) && row.addressIds.length > 0) {
    // 使用深拷贝避免引用问题
    addressArray.value = JSON.parse(JSON.stringify(row.addressIds));
    console.log("从 addressIds 设置地区数组:", addressArray.value);
  }
  // 如果没有 addressIds，但有地区 ID，则构建数组
  else if (row.country || row.province || row.city || row.district) {
    const ids: string[] = [];
    if (row.country) ids.push(String(row.country));
    if (row.province) ids.push(String(row.province));
    if (row.city) ids.push(String(row.city));
    if (row.district) ids.push(String(row.district));

    addressArray.value = ids;
    console.log("从地区 ID 构建的地区数组:", addressArray.value);
  }
};

// 删除
const handleDelete = (row: SchoolType) => {
  ElMessageBox.confirm("确认删除该学校吗？", "提示", {
    type: "warning",
  }).then(async () => {
    try {
      await deleteSchoolById(row.id);
      ElMessage.success("删除成功");
      getTableData();
    } catch (error) {
      console.error("删除学校失败:", error);
    }
  });
};

// 更新 levelStr
const updateLevelStr = (level: number) => {
  if (!level) return;

  const options = dictStore.getDictionary("school_level");
  const option = options.find((opt) => opt.value === level.toString());
  if (option) {
    form.levelStr = option.label;
  }
};

// 监听 level 变化
watch(
  () => form.level,
  (newLevel) => {
    if (newLevel) {
      updateLevelStr(newLevel);
    }
  },
  { immediate: true }
);

// 提交表单
const handleSubmit = async () => {
  if (!formRef.value) return;

  // 检查是否选择了地区
  if (!form.country || !form.province || !form.district) {
    ElMessage.warning("请选择完整的地区信息");
    return;
  }

  // 提交前强制设置 levelStr
  if (form.level !== undefined && form.level !== null) {
    const options = dictStore.getDictionary("school_level");
    console.log("options:", options);
    const option = options.find((opt) => opt.value === String(form.level));
    if (option) {
      form.levelStr = option.label;
      console.log("设置的 levelStr:", form.levelStr);
    }
  }

  await formRef.value.validate(async (valid) => {
    if (valid) {
      try {
        // 打印提交的数据，检查 levelStr
        console.log("提交的完整表单数据:", JSON.stringify(form));

        await saveAndUpdateSchool(form);
        ElMessage.success(dialogType.value === "add" ? "新增成功" : "编辑成功");
        dialogVisible.value = false;
        getTableData();
      } catch (error) {
        console.error("保存学校失败:", error);
      }
    }
  });
};

// 分页
const handleSizeChange = (val: number) => {
  searchform.pageSize = val;
  getTableData();
};

const handleCurrentChange = (val: number) => {
  searchform.pageNum = val;
  getTableData();
};

// 处理地址变化
const handleAddressChange = (regions: RegionType[]) => {
  if (regions && regions.length > 0) {
    // 设置地址ID列表
    form.addressIds = regions.map((region) => region.id);

    // 设置各个地区的ID和字符串
    regions.forEach((region) => {
      switch (region.level) {
        case RegionLevelEnum.COUNTRY:
          form.country = +region.id;
          form.countryStr = region.name;
          break;
        case RegionLevelEnum.PROVINCE:
          form.province = +region.id;
          form.provinceStr = region.name;
          break;
        case RegionLevelEnum.CITY:
          form.city = +region.id;
          form.cityStr = region.name;
          break;
        case RegionLevelEnum.DISTRICT:
          form.district = +region.id;
          form.districtStr = region.name;
          break;
      }
    });
  }
};

// 对话框关闭事件
const handleDialogClosed = () => {
  // 重置表单和地区选择
  if (formRef.value) {
    formRef.value.resetFields();
  }

  // 重置地区选择数组
  addressArray.value = [];

  // 重置 form 数据
  Object.assign(form, {
    name: "",
    logo: "",
    level: 1,
    levelStr: "",
    address: "",
    phone: "",
    email: "",
    website: "",
    addressIds: [] as string[],
    country: 0,
    countryStr: "",
    province: 0,
    provinceStr: "",
    city: 0,
    cityStr: "",
    district: 0,
    districtStr: "",
  });

  // 增加 dialogKey，下次打开时强制重新渲染
  dialogKey.value++;
};

// 初始化
onMounted(() => {
  getTableData();
});
</script>

<style lang="scss" scoped>
:deep(.el-image-viewer__wrapper) {
  z-index: 99999 !important;
}

:deep(.el-image-viewer__mask) {
  z-index: 99998 !important;
}

:deep(.el-image-viewer__canvas) {
  z-index: 99999 !important;
}

:deep(.el-image-viewer__actions) {
  z-index: 99999 !important;
}

:deep(.el-image-viewer__actions__inner) {
  z-index: 99999 !important;
}

:deep(.el-image-viewer__btn) {
  z-index: 99999 !important;
}

:deep(.el-image-viewer__close) {
  z-index: 99999 !important;
}

:deep(.el-image-viewer__prev) {
  z-index: 99999 !important;
}

:deep(.el-image-viewer__next) {
  z-index: 99999 !important;
}

:deep(.el-image-viewer__canvas img) {
  z-index: 99999 !important;
}

:deep(.el-image-viewer__loading) {
  z-index: 99999 !important;
}

:deep(.el-image-viewer__loading-text) {
  z-index: 99999 !important;
}

:deep(.el-image-viewer__loading-spinner) {
  z-index: 99999 !important;
}

:deep(.el-image-viewer__loading-icon) {
  z-index: 99999 !important;
}

:deep(.el-image-viewer__loading-icon-inner) {
  z-index: 99999 !important;
}

:deep(.el-image-viewer__loading-icon-inner::before) {
  z-index: 99999 !important;
}

:deep(.el-image-viewer__loading-icon-inner::after) {
  z-index: 99999 !important;
}
</style>

<style scoped lang="scss">
.search-bar {
  margin-bottom: 20px;
}

.operation-bar {
  margin-bottom: 20px;
}

.pagination {
  margin-top: 20px;
  display: flex;
  justify-content: flex-end;
}

:deep(.el-table .cell) {
  white-space: nowrap;
}
</style>
